<?php

namespace app\home\services;

use app\common\libs\InsideApi;
use app\common\loader\ModelMerchant;
use app\common\loader\ModelShop;
use app\common\loader\ModelVirtual;
use app\common\loader\Services;
use app\common\traits\WechatTrait;
use app\home\loader\Model;
use think\Exception;
use think\facade\Cache;

class SystemService
{
    use WechatTrait;

    // 登录缓存有效期
    protected const TOKEN_TIMEOUT = DAY_SECOND * 3;
    // 登录权限的前缀
    protected const TOKEN_PREFIX = 'HOME_LOGIN_TOKEN';


    // 微信入口
    public function entry(string $mer_id)
    {
        $result = $this->getOauth(['type' => 2, 'scope' => 0, 'mer_id' => $mer_id]);
        header("location:" . $result['url']);
        exit;

    }

    /**
     * 微信登录
     * @param array $params
     * @param int $app
     * @return array|void
     * @throws Exception
     */
    public function wxLogin(array $params, int $app)
    {
        try {
            $mer_info = ModelMerchant::MerchantInfo()->where('mer_id', $params['mkey'])
                ->field('mer_id,title,mobile,phone,company_name,status,end_time')
                ->find();
            if (empty($mer_info) || $mer_info['status'] !== 1 || $mer_info['end_time'] < date('Y-m-d')) {
                api_exception(API_ERROR, '商户已停用,请联系经销商');
            }
            $wx_info = $this->wxOauth($params);
            $shoppers = ModelShop::ShopSalesman()->where('mer_id', $params['mkey'])->where('open_id', $wx_info['openid'])->field('id,shop_id,mer_id,name,open_id,union_id,status,recheck')->find();
            if (!empty($shoppers)) {
                if ($shoppers['recheck'] != 1) {
                    $login_type = 3;//未审核
                } elseif ($shoppers['status'] != 1) {
                    $login_type = 4;//禁用
                    $guide = [
                        'id' => $shoppers['id'],
                        'username' => $shoppers['name']
                    ];
                } else {
                    $token = $this->saveToken($shoppers, $app);
                    $login_type = 0;//登录成功
                }
            } elseif (empty($wx_info['nickname'])) {
                $url = $this->getOauth(['type' => 2, 'scope' => 1, 'mer_id' => $params['mkey']]);
                $login_type = 1;//导购授权
            } elseif (isset($wx_info['nickname'])) {
                $login_type = 2;//授权成功
            }
            $info =  ['company' => $mer_info['company_name'] ?? '', 'mobile' => $mer_info['phone'] ?? ''];
            if (!isset($login_type)) {
                api_exception(API_ERROR, '登录失败，请重新登录');
            }
            return [
                'authorization' => $token ?? '',
                "mer_id" => $params['mkey'] ?? '',
                "openid" => $wx_info['openid'] ?? '',
                'auth_url' => $url['url'] ?? '',
                'login_type' => $login_type ?? 5,
                'mer_info' => $info ?? [],
                'shopper' => $guide ?? []
            ];
        } catch (Exception $e) {
            throw $e;
        }
    }

    /**
     * 保存到token到缓存中
     * @param array $user_info 用户信息
     * @param int $app app类型
     * @return mixed
     * @throws \yiqiniu\extend\exception\ApiException
     */
    public function saveToken(array $user_info, int $app = 9)
    {
        //生成加密TOKEN
        $tokens = config('config.token', []);
        $tokenKey = $tokens['jwt'] ?? '';
        if (empty($tokenKey)) {
            api_exception(401, 'secret_key不能为空');
        }
        $token = Services::Helper()->getToken($tokenKey, $tokens['expire'] ?? 0, $user_info);
        $authorization = $token['access_token'] ?? $token;
        if (empty($authorization)) {
            api_exception(401, 'access_token加密有误');
        }
        //保存TOKEN入缓存
        Cache::set(self::TOKEN_PREFIX . $app . '_' . $user_info['id'], $authorization, self::TOKEN_TIMEOUT);
        return $authorization;
    }

    /**
     * 验证登录
     * @param array $user 验证用户内容
     * @param string $msg 错误信息
     * @return array|false
     * @throws \think\Exception
     */
    public function verityLogin(array $user, string &$msg)
    {
        // 验证导购,判断用户是否禁用
        $userInfo = ModelShop::ShopSalesman()->validUserInfo($user, $msg);
        if (empty($userInfo)) {
            return false;
        }
        $mer_status = ModelMerchant::MerchantInfo()->checkMerchantStatus($userInfo['mer_id']);
        if (empty($mer_status)) {
            $msg = '商户已被禁用,请联系客服';
            return false;
        }
        $shop_status = ModelShop::Shop()->checkShopStatus($userInfo['mer_id'], $userInfo['shop_id']);
        if (empty($shop_status)) {
            $msg = '门店已被禁用,请联系客服';
            return false;
        }
        return [
            "user_id" => $userInfo["id"],
            "mer_id" => $userInfo["mer_id"],
            "username" => $userInfo["name"],
            "mobile" => $userInfo["mobile"],
            "shop_id" => $userInfo["shop_id"],
            "open_id" => $userInfo["open_id"],
            'union_id' => $userInfo['union_id'],
            'point' => $userInfo['point'],
        ];
    }

    /**
     * 用户注册验证
     * @return array|false
     * @throws \think\Exception
     */

    /**
     * 注册导购
     * @param array $data 导购信息
     * @return int  用户的ID
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function wxRegisterSalesMan(array $data): array
    {
        $result = ['result' => 0, 'msg' => '', 'data' => []];
        //验证商户，是否禁用，是否存在
        $merInfo = ModelMerchant::MerchantInfo()->checkMerchantStatus($data['mer_id']);
        if (empty($merInfo)) {
            throw  new Exception('经销商不存在或已禁用,请联系经销商.', API_ERROR);
        }
        // 获取微信失败,返回重新认证的接口
        $wx_info = Services::Helper()->getWechatUserInfo($data['open_id']);
        if ($wx_info['bind'] === 0) {
            $url = $this->getOauth(['type' => 2, 'scope' => 1, 'mer_id' => $data['mer_id']]);
            $result['result'] = API_ERROR;
            $result['msg'] = '微信授权过期,重新授权';
            $result['data'] = ['url' => $url];
            return $result;
        }

        // 验证导购,新增还是更新 1更新。 2添加， 门店不可重复添加该手机号的用户
        $resultInfo = ModelShop::ShopSalesman()->saveUserInfo($data, $wx_info);
        if ($resultInfo['id'] < 1) {
            throw  new Exception('操作失败', API_ERROR);
        }
        $result['result'] = API_SUCCESS;
        $result['msg'] = $resultInfo['msg'];

        $result['data'] = [
            'company' => $merInfo['company_name'],
            'mobile' => $merInfo['phone'],
        ];
        // 注册成功发送审核通知
        event('RegisterSuccess', $data);
        return $result;
    }


    /**
     * 微信JSSDK使用配置信息
     */
    public function getConfig(array $params): array
    {
        $config = config('wechat');
        $timestamp = time();
        $noncestr = $config['noncestr'];
        $ticket = cache('session_ticket_token_' . $config['app_id']);
        if (empty($ticket)) {
            $res = InsideApi::Wechat()->Oauth()->GetJsapiTicket(['client_id' => $config['app_id'] ?? '']);
            if (empty($res) || $res['code'] != 200) {
                api_exception(400, $res['msg'] ?? '');
            }
            $ticket = $res['data']['ticket'] ?? '';
            cache('session_ticket_token_' . $config['app_id'], $ticket, 7200);
        }
        $data = [
            "noncestr" => $noncestr,
            "jsapi_ticket" => $ticket,
            "timestamp" => $timestamp,
            "url" => $params['url'] ?? ''
        ];
        // 内容排序
        $array_key = array_keys($data);
        array_multisort($array_key, SORT_ASC, $data);
        $sign = '';
        foreach ($data as $key => $value) {
            $sign .= '&' . $key . '=' . $value;
        }
        $sign = trim($sign, '&');
        $data['signature'] = sha1($sign);
        $data['appId'] = $config['app_id'];
        $data['jsApiList'] = $config['jsApiList'];
        $data['nonceStr'] = $noncestr;
        unset($data['jsapi_ticket'], $data['url'], $data['noncestr']);
        return $data;
    }

    /**
     * 门店列表
     */
    public function getShopList(array $params): array
    {
        $list = [];
        if (!empty($params['mer_id'])) {
            $list = ModelShop::Shop()->where($params['where'] ?? [])
                ->field('id,title,lat,lng')->select();
            if (!empty($list)){
                foreach ($list as $key => $v){
                    if (empty($v['lng']) || empty($v['lat']) || empty($params['lng']) || empty($params['lat'])){
                        $list[$key]['m'] = 10000000000;
                    }else {
                        $list[$key]['m'] = getDistance($params['lng'], $params['lat'], $v['lng'], $v['lat']);
                    }
                    unset($list[$key]['lng'] , $list[$key]['lat']);
                }
                 array_multisort(array_column($list,'m'),SORT_ASC,$list);
//                 $list = array_slice($list, 0, 10);//限制数据
            }
        }
        return $list;
    }

    /**
     * 获取用户信息
     * @param $mer_id |商户id
     * @param $user_id |用户id
     */
    public function userInfo($mer_id, $user_id)
    {
        $result = [
            'nickname' => '',
            'head_img' => '',
            'point' => '',
            'address_id' => 0,
            'phone' => 0,
        ];
        $data = ModelShop::ShopSalesman()->getSalesmanUserInfo(
                ['mer_id' => $mer_id, 'id' => $user_id],
                ['nickname','head_img','point','mobile']);
        $data['address_id'] = ModelMerchant::MerchantMemberSalesmanAddress()
                ->where(['mer_id' => $mer_id, 'user_id' => $user_id,'def' => 1])
                ->value(null,'id') ?? 0;
        $data['phone'] = ModelMerchant::MerchantInfo()
                ->where('mer_id' , $mer_id)
                ->value(null,'phone') ?? '';
        return  array_merge($result , $data);
    }
}
